package 反射;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//Java Constructor类
//Constructor是一个类,位于java.lang.reflect包下，它代表某个类的构造方法，用来管理所有的构造函数的类.
//
//定义
//public final class Constructor<T> extends AccessibleObject implements GenericDeclaration, Member
//1. 提供关于类的单个构造方法的信息以及对它的访问权限。
//2. 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换，但是如果发生收缩转换，则抛出 IllegalArgumentException
//
//获取Constructor类对象一共有4种方法,全部都在Class类中:
//
//1. getConstructors()：获取类中的公共方法
//
//2. getConstructor(Class[] params): 获取类的特定构造方法,params参数指定构造方法的参数类型
//
//3. getDeclaredConstructors(): 获取类中所有的构造方法(public、protected、default、private)
//
//4. getDeclaredConstructor(Class[] params): 获取类的特定构造方法,params参数指定构造方法的参数类型
//
//举例
//1）得到这个类的所有构造方法：如得到上面示例中Person类的所有构造方法
//Constructor[] cons = Class.forName(“cn.itheima.Person”).getConstructors();
//2）获取某一个构造方法：
//Constructor con=Person.class.getConstructor(String.class,int.class);
//
//常用方法
//public static void main(String[] args) throws Exception {
//    //使用反射第一步:获取操作类ConstructorDemo所对应的Class对象
//    Class <?>cls = Class.forName("Constructor类");
//
//    //获取默认的构造函数
//    Constructor constructor1 = cls.getConstructor(new Class[] {});
//    //获取构造函数信息
//    System.out.println("修饰符: " + Modifier.toString(constructor1.getModifiers()));
//    System.out.println("构造函数名: " + constructor1.getName());
//    System.out.println("参数列表: " + constructor1.getParameterTypes());
//    //通过默认的构造函数创建ConstructorDemo类的实例
//    Object obj = constructor1.newInstance();
//    System.out.println("调用默认构造函数生成实例:" + obj.toString());
//
//    System.out.println("===============================================");
//
//    //获取带参数的构造函数
//    Constructor constructor2 = cls.getConstructor(new Class[] {
//        int.class,
//        String.class
//    });
//    System.out.println("修饰符: " + Modifier.toString(constructor2.getModifiers()));
//    System.out.println("构造函数名: " + constructor2.getName());
//    System.out.println("参数列表: " + constructor2.getParameterTypes());
//    //获取构造函数信息
//    //通过带参数的构造函数创建ConstructorDemo类的实例
//    Object obj2 = constructor2.newInstance(new Object[] {
//        33,
//        "haha"
//    });
//    System.out.println("调用带参数构造函数生成实例:" + obj2.toString());
//}
//创建实例对象
//public class CreateClassDemo {
//public class Constructor类 {
//    public static void main(String[] args) throws Exception {
//        createPersonClass_2();
//    }
//
//    public static void createPersonClass_2() throws Exception //通过Constructor对象来创建类实例方法
//    {
//        //获取Person类的Class对象
//        String className = "cn.itheima.Person";
//        Class clazz = Class.forName(className);
//        //Class clazz=Person.class;
//        //获取指定构造函数的类实例
//        Constructor con = clazz.getConstructor(String.class, int.class);
//        Person p = (Person) con.newInstance("lisi", 30);
//        System.out.println(p.toString());
//    }
//}
//1、创建实例时newInstance方法中的参数列表必须与获取Constructor的方法getConstructor方法中的参数列表一致。
//
//2、newInstance()：构造出一个实例对象，每调用一次就构造一个对象。
//
//3、利用Constructor类来创建类实例的好处是可以指定构造函数，而Class类只能利用无参构造函数创建类实例对象。
//
//例子
class Car1{

    public Car1() {
        // TODO Auto-generated constructor stub
        System.out.println("Car()");
    }
    public Car1(int i){
        System.out.println("Car(i)");
    }
    public void run(){
        System.out.println("----running");
    }    
}
public class Constructor类 {
    public static void main(String[] args) {
        Class<Car1> clazz = Car1.class;
        
        try {
        	Constructor<Car1> constructor = clazz.getConstructor();
            Car1 car =  constructor.newInstance();
            car.run();
            Constructor<Car1> constructor2= clazz.getConstructor(int.class);
            Car1 car2 = constructor2.newInstance(2);
//            car.run();
            car2.run();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
//执行结果：
//
//Car()
//Car(i)
//----running
//----running
//注意:
//Car的构造器，必须显示声明。不然Constructor.newInstance()报错。
//
//总结
//1. Constructor类代表某个类中的一个构造方法。很多类都有构造方法，一个类还可能有多个构造方法。
//
//2. 通过创建Constructor的对象实例，我们可以创建源对象。





